<template>
    <VueDraggable
        :list="value"
        :disabled="disabled"
        :animation="200"
        :group="group"
        chosen-class="vo-grids-chosen"
        filter=".filter-bar"
        handle=".vo-drag-bar"
        ghost-class="vo-grids-ghost"
    >
        <transition-group class="vo-grids" type="transition" name="flip-list" :style="gridsStyle" tag="div">
            <div class="vo-grids-item" :class="{
                'filter-bar': item.disabled
            }" v-for="(item, index) in value" :key="`grid_`+index">
                <div class="vo-grids-item-content">
                    {{item.name}}
                </div>
                <i v-if="draggable && !item.disabled" class="el-icon-rank vo-drag-bar" @click.stop></i>
            </div>
        </transition-group>
    </VueDraggable>
</template>

<script>
import VueDraggable from 'vuedraggable'
import { clone } from '@/utils/clone'

export default {
    name: 'VoGrids',
    components: {
        VueDraggable
    },
    props: {
        value: {
            type: Array,
            default: () => []
        },
        // 行
        rows: {
            type: Number,
            default: 1
        },
        // 列
        cols: {
            type: Number,
            default: 1
        },
        // 间隔
        gap: {
            type: [Number, String],
            default: 10
        },
        // 大小
        size: {
            type: [Number, String],
            default: 100
        },
        // 模式 single 单个 | multiple 多个
        mode: {
            type: String,
            default: 'multiple',
            validator: (value) => ['single', 'multiple'].indexOf(value) !== -1
        },
        // 是否可拖拽
        draggable: Boolean,
        // 是否禁用
        disabled: Boolean,
        // 组
        group: {
            type: String,
            default: 'grids'
        }
    },
    data() {
        return {
            gridsData: []
        }
    },
    computed: {
        gridsStyle() {
            const { rows = 0, cols = 0, gap = 0, size = 0 } = this;
            const gapResult = typeof gap === 'number' ? `${gap}px` : (gap || 0)
            const sizeResult = typeof size === 'number' ? `${size}px` : (size || 0)

            return {
                gridTemplateRows: `repeat(${rows}, ${sizeResult})`,
                gridTemplateColumns: `repeat(${cols}, ${sizeResult})`,
                gap: gapResult
            }
        },
    },
    methods: {
        dataEmit(key, data) {
            this.$emit('input', data)
        },
        /**
         * 数据操作 反转 | x轴反转 | y轴反转 | 偶数行反转 | 奇数行反转 | 偶数列反转 | 奇数列反转
        */
        // 反转
        reverse() {
            const data = clone(this.value)
            data.reverse()
            this.dataEmit('reverse', data)
        },
        // x轴反转
        xReverse() {
            const data = clone(this.value)
            const { rows, cols } = this;
            const map = Array(rows).fill('').map(e => {
                return data.splice(0, cols)
            })
            const list = map.reverse().flat()
            this.dataEmit('xReverse', list)
        },
        // y轴反转
        yReverse() {
            const data = clone(this.value)
            const { rows, cols } = this;
            const map = Array(rows).fill('').map(e => {
                return data.splice(0, cols)
            })
            map.forEach(e => e.reverse())
            const list = map.flat()
            this.dataEmit('yReverse', list)
        },
        // 偶数行反转
        evenRowReverse() {
            const data = clone(this.value)
            const { rows, cols } = this;
            const map = Array(rows).fill('').map(e => {
                return data.splice(0, cols)
            })
            map.forEach((e, i) => {
                if (i % 2 !== 0) {
                    e.reverse()
                }
            })
            const list = map.flat()
            this.dataEmit('evenRowReverse', list)
        },
        // 奇数行反转
        oddRowReverse() {
            const data = clone(this.value)
            const { rows, cols } = this;
            const map = Array(rows).fill('').map(e => {
                return data.splice(0, cols)
            })
            map.forEach((e, i) => {
                if (i % 2 === 0) {
                    e.reverse()
                }
            })
            const list = map.flat()
            this.dataEmit('oddRowReverse', list)
        },
        // 偶数列反转
        evenColReverse() {
            const data = clone(this.value)
            const { rows, cols } = this;
            const map = []
            for (let i = 0; i < cols; i++) {
                map[i] = Array(rows).fill('').map((e, n) => {
                    return data[n * cols + i]
                })
            }
            map.forEach((e, i) => {
                if (i % 2 !== 0) {
                    e.reverse()
                }
            })
            const list = []
            for (let i = 0; i < rows; i++) {
                map.forEach(e => {
                    list.push(e[i])
                })
            }
            this.dataEmit('evenColReverse', list)
        },
        // 奇数列反转
        oddColReverse() {
            const data = clone(this.value)
            const { rows, cols } = this;
            const map = []
            for (let i = 0; i < cols; i++) {
                map[i] = Array(rows).fill('').map((e, n) => {
                    return data[n * cols + i]
                })
            }
            map.forEach((e, i) => {
                if (i % 2 === 0) {
                    e.reverse()
                }
            })
            const list = []
            for (let i = 0; i < rows; i++) {
                map.forEach(e => {
                    list.push(e[i])
                })
            }
            this.dataEmit('oddColReverse', list)
        },
    }
}
</script>

<style lang="scss" scoped>
.flip-list-move {
  transition: transform 0.5s;
}
.vo-grids-chosen{
    box-shadow: 0px 0px 4px 1px #ccc;
    background: yellowgreen;
}
.vo-grids-ghost{
    background: skyblue;
}
.vo-grids{
    display: grid;
    // grid-auto-flow: column;
    // grid-template-columns: repeat(0, 100px);
    // grid-template-rows: repeat(0, 100px);
    // gap: 10px;
    .vo-grids-item{
        position: relative;
    }
    .vo-drag-bar{
        position: absolute;
        top: 0;
        right: 0;
        z-index: 1;
        cursor: grab;
    }
    .vo-grids-item-content{
        width: 100%;
        height: 100%;
        border: 1px solid #ccc;
        box-sizing: border-box;
        // display: flex;
        // align-items: center;
        // justify-content: center;
        position: relative;
    }
}
</style>
